package org.easydarwin.util;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;

import org.easydarwin.easyrtc.R;
import org.easydarwin.easyrtc.TheApp;
import org.easydarwin.network.NetConfig;
import org.easydarwin.network.RequestManager;
import org.easydarwin.network.StatusConstant;
import org.easydarwin.network.VolleyCallBack;
import org.easydarwin.network.result.VolleyResult;
import org.easydarwin.view.dialogs.DialogDefaultLoading;
import org.json.JSONException;
import org.json.JSONObject;

import com.android.volley.AuthFailureError;
import com.android.volley.DefaultRetryPolicy;
import com.android.volley.NetworkResponse;
import com.android.volley.Request;
import com.android.volley.Request.Method;
import com.android.volley.Response;
import com.android.volley.RetryPolicy;
import com.android.volley.VolleyError;
import com.android.volley.VolleyLog;
import com.android.volley.toolbox.HttpHeaderParser;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.JsonRequest;
import com.android.volley.toolbox.StringRequest;

import android.app.Activity;
import android.content.Context;
import android.os.Looper;
import android.widget.Toast;

public class VolleyUtils {
    private Context context;
    private DialogDefaultLoading dialogUtils;
    private static VolleyUtils instance;

    public static VolleyUtils getInstance(Context context){
        if(null == instance){
            instance = new VolleyUtils(context);
        }
        return instance;
    }

    private VolleyUtils(Context context) {
        super();
        this.context = context;
        dialogUtils = new DialogDefaultLoading(context);
    }


    public void sendPostRequest(String url , JSONObject jsonObject , final VolleyResult v ,final boolean isDialog){
        if (!NetWorkUtil.isNetworkConnected(context)) {
            Toast.makeText(context, ResourceUtil.getStringResource(context , R.string.network_error), Toast.LENGTH_SHORT).show();
            return;
        }
        if (isDialog) {
            dialogUtils.dismiss();
        }
        JsonRequest<JSONObject> jsonRequest = new JsonObjectRequest(Request.Method.POST,url, jsonObject,
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        LogUtil.d( "response -> " + response.toString());
                        v.jsonSuccess(response , "");
                        if (isDialog) {
                            dialogUtils.dismiss();
                        }
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                LogUtil.e( error);
                v.failure(error.getMessage() , "");
                if (isDialog) {
                    dialogUtils.dismiss();
                }
            }
        })
        {
            @Override
            public Map<String, String> getHeaders() {
                HashMap<String, String> headers = new HashMap<String, String>();
                headers.put("Accept", "application/json");
                headers.put("Content-Type", "application/json; charset=UTF-8");
                return headers;
            }

        };
        jsonRequest.setRetryPolicy(new DefaultRetryPolicy());
        RequestManager.addRequest(context , jsonRequest);
    }

    public void sendInfo2(final String url, JSONObject jsonBody ,
                          final VolleyResult v, final boolean isDialog) {
        if (!NetWorkUtil.isNetworkConnected(context)) {
            Toast.makeText(context, ResourceUtil.getStringResource(context ,R.string.network_error), Toast.LENGTH_SHORT).show();
            return;
        }
        final String requestBody = jsonBody.toString();

        StringRequest stringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                LogUtil.i( "========================"+response);
                if (isDialog) {
                    dialogUtils.dismiss();
                }
                v.success(response , "");
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                LogUtil.e("==============="+error.toString());
                if (isDialog) {
                    dialogUtils.dismiss();
                }
                v.failure(error.getMessage() , "");
            }
        }) {
            @Override
            public String getBodyContentType() {
                return "application/json; charset=utf-8";
            }

            @Override
            public byte[] getBody() throws AuthFailureError {
                try {
                    return requestBody == null ? null : requestBody.getBytes("utf-8");
                } catch (UnsupportedEncodingException uee) {
                    VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", requestBody, "utf-8");
                    return null;
                }
            }

            @Override
            protected Response<String> parseNetworkResponse(NetworkResponse response) {
                String responseString = "";
                if (response != null) {
                    responseString = String.valueOf(response.statusCode);
                    // can get more details such as response.headers
                }
                LogUtil.i("==============responseString = " + responseString);
                return Response.success(responseString, HttpHeaderParser.parseCacheHeaders(response));
            }
        };
        if (isDialog) {
            dialogUtils.show();
        }
        RequestManager.addRequest(context, stringRequest);
    }

    public void sendInfo(final String method, final String[] parems,
                         final VolleyResult v, int METHOD, final boolean isDialog) {

        if (!NetWorkUtil.isNetworkConnected(context)) {
            Toast.makeText(context, ResourceUtil.getStringResource(context ,R.string.network_error), Toast.LENGTH_SHORT).show();
            v.failure(ResourceUtil.getStringResource(context ,R.string.network_error), method);
            return;
        }
        
        StringRequest stringRequest = new StringRequest(METHOD,
                NetConfig.getBaseUrl() + method, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                try {
                    if (isDialog) {
                        dialogUtils.dismiss();
                    }
                    LogUtil.d(" ================response="+ NetConfig.getBaseUrl() + method + "---" + response);
//                    JSONObject jsonObject = new JSONObject(response);
                    v.success(response , method);
                } catch (Exception e) {
                    e.printStackTrace();
                    v.failure(e.getMessage() , method);
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                v.failure(error.toString(), method);
                if (isDialog) {
                    dialogUtils.dismiss();
                }
                Toast.makeText(context, ResourceUtil
                        .getStringResource(context ,R.string.network_error), Toast.LENGTH_SHORT).show();
            }
        }) {
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                return getParamMap(method, parems);
            }

            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                return initVolleyHeader();
            }
        };
        if (isDialog) {
            Activity act = (Activity) context;
            if(!act.isFinishing()){
                dialogUtils.show();
            }
        }
        RequestManager.addRequest(context, stringRequest);
    }
    
    
    private void showError(int status){
    	switch (status) {
//    	case StatusConstant.result_no_data:
//    		Toast.makeText(context, ResourceUtil.getStringResource(R.string.result_no_data), Toast.LENGTH_SHORT).show();
//    		break;

		}
    }

    private Map<String, String> getParamMap(String method, String[] parems) {
        Map<String, String> map = new HashMap<String, String>();
        if (method.equals(NetConfig.userLogin)) {
            map.put("account", parems[0]);
            map.put("password", parems[1]);
        }else if (method.equals(NetConfig.allRoles)) {
            map.put("token", "");
        }
        LogUtil.i("======================params:" + map.toString());
        return map;
    }

    /**
     * @author hu
     * @time 2015-11-19
     */
    public static void sendPostMethod(final String url,
                                      final Map<String, String> map, final VolleyCallBack v,
                                      final boolean isDialog, Context context) {
        if (map != null) {
            LogUtil.d(url + "请求参数================="+ map.toString());
        }
        if (!isDialog) {
            sendPostMethod(url, map, v, context);
        } else {
            DialogDefaultLoading dialogUtils = new DialogDefaultLoading(context);
            sendPostMethod(url, map, v, dialogUtils, context);
        }
    }

    /**
     * @author hu
     * @time 2015-11-19
     */
    public static void sendPostMethod(final String url,
                                      final Map<String, String> map, final VolleyCallBack v,
                                      Context context) {
        sendPostMethod(url, map, v, null, context);
    }

    public static final int VOLLEYCALLBACK_STATUS_NOT_TRUE = 0;
    public static final int VOLLEYCALLBACK_CODE_NOT_ZERO = 1;
    public static final int VOLLEYCALLBACK_HTTP_ASK_FAIL = 2;
    public static final int VOLLEYCALLBACK_PARSE_JSON_ERROR = 3;

    /**
     * 对数据的返回状态及返回码统一处理可调用此方法
     *
     * @author hu
     * @time 2015-11-19
     */
    public static void sendPostMethod(final String url,
                                      final Map<String, String> map, final VolleyCallBack v,
                                      final DialogDefaultLoading dialogUtils, final Context context) {
        if(map!=null){
            LogUtil.i(url + "--请求参数:"+ map.toString());
        }
        if (!NetWorkUtil.isNetworkConnected(context)) {
            boolean isMinaThread = Thread.currentThread() == Looper.getMainLooper().getThread();
            if (isMinaThread) {//判断此线程是否为主线程
                Toast.makeText(context, ResourceUtil
                        .getStringResource(context ,R.string.network_error), Toast.LENGTH_SHORT).show();
            }
            v.failure(ResourceUtil.getStringResource(context ,R.string.network_error),
                    url, VOLLEYCALLBACK_HTTP_ASK_FAIL);
            return;
        }

        final StringRequest stringRequest = new StringRequest(Method.POST, url,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        LogUtil.d("volley = "+ url + "---" + response);
                        if (dialogUtils != null)
                            dialogUtils.dismiss();
                        try {
                            v.success(response, url);
                        } catch (Exception e) {
                            e.printStackTrace();
                            Toast.makeText(context, ResourceUtil
                                    .getStringResource(context ,R.string.request_json_parse_exception), Toast.LENGTH_SHORT).show();
                            v.failure("",
                                    url, VOLLEYCALLBACK_PARSE_JSON_ERROR);
                        }
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                try {
                    if (dialogUtils != null) {
                        dialogUtils.dismiss();
                    }

                    Toast.makeText(context, ResourceUtil
                            .getStringResource(context ,R.string.network_error), Toast.LENGTH_SHORT).show();

                    v.failure(ResourceUtil
                                    .getStringResource(context ,R.string.network_error),
                            url, VOLLEYCALLBACK_HTTP_ASK_FAIL);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }) {

            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                return map;
            }

            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                return initVolleyHeader();
            }
        };

        if (dialogUtils != null) {
            dialogUtils.show();
        }
        RequestManager.addRequest(context, stringRequest);
    }

    /**
     * 需要对返回数据的状态或返回码进行特殊判断处理的地方可调用此方法
     *
     * @author hu
     * @time 2015-11-19
     */
    public static void sendPostMethodTakeCallBack(final String url,
                                                  final Map<String, String> map, final VolleyCallBack v,
                                                  final Context context, final boolean showDialog) {

    	
        if (!NetWorkUtil.isNetworkConnected(context)) {
            Toast.makeText(context, ResourceUtil
                    .getStringResource(context ,R.string.network_error), Toast.LENGTH_SHORT).show();
            v.failure(
            		ResourceUtil.getStringResource(context ,R.string.network_error),
                    url, VOLLEYCALLBACK_HTTP_ASK_FAIL);
            return;
        }

        final DialogDefaultLoading dialogUtils = new DialogDefaultLoading(context);

        final StringRequest stringRequest = new StringRequest(Method.POST, url,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        LogUtil.d("volley = "+ url + "---" + response);
                        if (showDialog) {
                            dialogUtils.dismiss();
                        }
                        try {
                            v.success(response, url);
                        } catch (Exception e) {
                            e.printStackTrace();
                            Toast.makeText(context, ResourceUtil
                                    .getStringResource(context ,R.string.request_json_parse_exception), Toast.LENGTH_SHORT).show();
                        }
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(context, ResourceUtil
                        .getStringResource(context ,R.string.network_error), Toast.LENGTH_SHORT).show();
                if (showDialog) {
                    dialogUtils.dismiss();
                }
            }
        }) {

            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                return map;
            }

            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                return initVolleyHeader();
            }
        };
        try {
            if (showDialog)
                dialogUtils.show();
            RequestManager.addRequest(context, stringRequest);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void cancelAll(Object tag) {

        RequestManager.cancelAll(tag);
    }

    public static Map<String, String> initVolleyHeader() {
        Map<String, String> headers = new HashMap<String, String>();
        headers.put("Content-Type", "application/json");//
        headers.put("Accept", "application/json");//
        LogUtil.i("=======================headers = "  + headers.toString());
        return headers;
    }

    /**
     * 微信获取token接口
     *
     * @param url
     * @param map
     * @param v
     * @param context
     */
    public static void getWeixinNetData(final String url,
                                        final Map<String, String> map, final VolleyCallBack v,
                                        final Context context) {

    	
        if (!NetWorkUtil.isNetworkConnected(context)) {
            Toast.makeText(context, ResourceUtil
                    .getStringResource(context ,R.string.network_error), Toast.LENGTH_SHORT).show();
            v.failure(
            		ResourceUtil.getStringResource(context ,R.string.network_error),
                    url, VOLLEYCALLBACK_HTTP_ASK_FAIL);
            return;
        }
        final DialogDefaultLoading dialogUtils = new DialogDefaultLoading(context);

        final StringRequest stringRequest = new StringRequest(Method.POST, url,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        LogUtil.d("volley = " + url + "---" + response);
                        if (dialogUtils != null) {
                            dialogUtils.dismiss();
                        }
                        v.success(response, url);
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                try {
                    if (dialogUtils != null) {
                        dialogUtils.dismiss();
                    }
                    Toast.makeText(context, ResourceUtil
                            .getStringResource(context ,R.string.network_error), Toast.LENGTH_SHORT).show();
                    v.failure(ResourceUtil
                                    .getStringResource(context ,R.string.network_error),
                            url, VOLLEYCALLBACK_HTTP_ASK_FAIL);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }) {

            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                return map;
            }

            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                return initVolleyHeader();
            }
        };

        if (dialogUtils != null) {
            dialogUtils.show();
        }
        RequestManager.addRequest(context, stringRequest);
        // addRequestToQueue(context, stringRequest);
    }

    /**
     * 对数据的返回状态及返回码统一处理可调用此方法
     *
     * @author hu
     * @time 2015-11-19
     */
    public static void sendGetMethod(final String url, final VolleyCallBack v, final Context context) {
        if (!NetWorkUtil.isNetworkConnected(context)) {
            boolean isMinaThread = Thread.currentThread() == Looper.getMainLooper().getThread();
            if (isMinaThread) {//判断此线程是否为主线程
                Toast.makeText(context, ResourceUtil
                        .getStringResource(context ,R.string.network_error), Toast.LENGTH_SHORT).show();
            }
            v.failure(
            		ResourceUtil.getStringResource(context ,R.string.network_error),
                    url, VOLLEYCALLBACK_HTTP_ASK_FAIL);
            return;
        }

        final StringRequest stringRequest = new StringRequest(Method.GET, url,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        LogUtil.d("volley = " + url + "---" + response);
                        v.success(response, url);

                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                try {
                    Toast.makeText(context, ResourceUtil
                            .getStringResource(context ,R.string.network_error), Toast.LENGTH_SHORT).show();

                    v.failure(ResourceUtil
                                    .getStringResource(context ,R.string.network_error),
                            url, VOLLEYCALLBACK_HTTP_ASK_FAIL);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }) {
            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                return initVolleyHeader();
            }
        };

        RequestManager.addRequest(context, stringRequest);
    }

}
